/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "PBF邻接构建.h"


#include "core/CUDA_utils.cuh"



S_邻接索引计算::S_邻接索引计算(S_设备环境& ctx) {
	m_并行计算GPU参数set = 0;

	std::vector<S_着色器创建参数> 参数配置;
	参数配置 = {
		{0, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBO},
		{1, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBO},
		{2, E_着色阶段::e_计算着色, E_板载缓存类型::e_UBO},
	};

	f_gpu_create并行计算实例(ctx, "D:/U/Project/engine/资产/着色/2D/UI连接线相交检测.spv", 参数配置);

	m_Shader->f_alloc参数设置(&(m_并行计算GPU参数set));


}

void S_邻接索引计算::f_updateGPU参数(S_坐标数据* 数据) {
	m_坐标编码参数元素 = (S_板载缓存**)calloc(4, sizeof(S_板载缓存*));
	m_坐标编码参数元素数量 = 2;

	m_坐标编码参数元素[0] = 数据->m_坐标;
	m_坐标编码参数元素[1] = 数据->m_邻接;
	


	//f_setGPU参数布局(m_Shader, m_并行计算GPU参数set, { m_坐标编码参数元素, 0, m_坐标编码参数元素数量, 0 });



	
}

S_邻接单元构建::S_邻接单元构建(E_并行设备 device) {
	//m_单元大小 = 0.1;

	m_解算设备类型 = device;
	switch (device)
	{
	case e_CPU并行: {

	} break;

	case e_CUDA并行: {

	} break;

	case e_OpenCL并行: {

	} break;

	case e_GLSL并行: {

	} break;

	default:
		break;
	}

	//m_Data = {};

	//m_Data.m_TempVert = nullptr;
	//m_Data.m_体素索引 = nullptr;
	//m_Data.m_邻接索引_Key = nullptr;
	//m_Data.m_邻接索引_Value = nullptr;
	//m_Data.m_单元内邻接数量 = nullptr;

}

void S_邻接单元构建::f_构建粒子GPU邻接单元(vec3* pos, const uint64 num, uint32 线程块大小) {
	if (!num) return;

	//uint64 vn = m_Data.m_域属性.m_单元属性.m_分辨率.x * m_Data.m_域属性.m_单元属性.m_分辨率.y * m_Data.m_域属性.m_单元属性.m_分辨率.z;
	//if (num != m_Data.m_Num || m_Data.m_体素Num != vn) {
	//	m_Data.m_Num = num;
	//	m_Data.m_体素Num = vn;
		//ouf_分配单元区间GPU内存(m_Data);

		
	//}


	switch (m_解算设备类型)
	{
	case e_CPU并行: {

	} break;

	case e_CUDA并行: {
		//m_Data.m_TempVert = pos;
		//ouf_分配单元区间GPU内存(m_Data);
		//cuf_分类邻接单元(m_Data, pos, 线程块大小);
	} break;

	case e_OpenCL并行: {

	} break;

	case e_GLSL并行: {

	} break;

	default:
		break;
	}
	//cuf_排序邻接单元(m_Data, pos);
}

void S_邻接单元构建::f_构建粒子CUP邻接单元(vec3* pos, const uint64 num, uint32 线程块大小) {
	if (!num) return;

	//uint64 vn = m_Data.m_域属性.m_单元属性.m_分辨率.x * m_Data.m_域属性.m_单元属性.m_分辨率.y * m_Data.m_域属性.m_单元属性.m_分辨率.z;
	//if (num != m_Data.m_Num || m_Data.m_体素Num != vn) {
	//	m_Data.m_Num = num;
	//	m_Data.m_体素Num = vn;
		//ouf_分配单元区间GPU内存(m_Data);

	//	uvec3& 分辨率 = m_Data.m_域属性.m_单元属性.m_分辨率;
	//	m_cpu索引体素.resize(分辨率.x * 分辨率.y * 分辨率.z);
	//	m_cpuIndexsNum.resize(m_cpu索引体素.size());
	//	m_cpuIndexs.resize(m_Data.m_Num);	
	//}


	switch (m_解算设备类型)
	{
	case e_CPU并行: {

	} break;

	case e_CUDA并行: {
		//COUDA_CALL(cudaMalloc((void**)&(m_Data.m_TempVert), sizeof(vec3) * m_Data.m_Num));
		//cudaMemcpy(m_Data.m_TempVert, pos, m_Data.m_Num * sizeof(vec3), cudaMemcpyKind::cudaMemcpyHostToDevice);

		//cuf_分类邻接单元(m_Data, pos, 线程块大小);

		//cudaFree(m_Data.m_TempVert);
	} break;

	case e_OpenCL并行: {

	} break;

	case e_GLSL并行: {

	} break;

	default:
		break;
	}

	
	
	//cuf_排序邻接单元(m_Data, pos);
	//buf_数据拷贝回内存(m_cpuIndexs.data(), m_cpuIndexsNum.data(), m_cpu索引体素.data(), m_Data);
	std::cout << "构建粒子CUP邻接单元" << std::endl;
	//for (auto& e : m_cpuIndexsNum) if(e) std::cout << "e = " << int32(e) << std::endl;
}

void S_邻接单元构建::f_toCpu() {
	//uvec3& 分辨率 = m_Data.m_域属性.m_单元属性.m_分辨率;
	//m_cpu索引体素.resize(分辨率.x * 分辨率.y * 分辨率.z);
	//m_cpuIndexsNum.resize(m_cpu索引体素.size());
	//m_cpuIndexs.resize(m_Data.m_Num);
	//m_cpuIndexs.resize(4096);

	//buf_数据拷贝回内存(m_cpuIndexs.data(), m_cpuIndexsNum.data(), m_cpu索引体素.data(), m_Data);
}

uint32 S_邻接单元构建::f_get单元粒子数量(const uvec3& coord) {
	//uvec3 域坐标 = vec_转换(vec_Max((coord - m_Data.m_域属性.m_单元属性.m_域世界偏移), { 0,0,0 }) / m_Data.m_域属性.m_单元属性.m_单元大小);

	//m_Data.m_单元内邻接数量[]
	return uint32();
}

S_DomUnitIndex S_邻接单元构建::f_get单元粒子索引(const vec3& coord) {
	//uvec3 域坐标 = vec_转换(vec_Max((coord - m_Data.m_域属性.m_单元属性.m_域世界偏移), {0,0,0}) / m_Data.m_域属性.m_单元属性.m_单元大小);

	//uvec3& 分辨率 = m_Data.m_域属性.m_单元属性.m_分辨率;
	//uint64 id = f_坐标转线性索引(域坐标, { 分辨率.x, 分辨率.y, 分辨率.z});
	//id = m_cpu索引体素[id];


	S_DomUnitIndex 单元 = {};
	//单元.index = &m_cpuIndexs[id];
	//单元.num = m_cpuIndexsNum[id];

	return 单元;
}

S_DomUnitIndex S_邻接单元构建::f_get单元粒子索引(const uvec3& coord) {
	//uvec3& 分辨率 = m_Data.m_域属性.m_单元属性.m_分辨率;
	//uint64 id = f_坐标转线性索引(coord, { 分辨率.x, 分辨率.y, 分辨率.z });
	

	S_DomUnitIndex 单元 = {};
	//单元.num = m_cpuIndexsNum[id];
	//id = m_cpu索引体素[id];
	//单元.index = &m_cpuIndexs[id];
	
	return 单元;
}

bool S_邻接单元构建::f_单元是否有填充(const uvec3& coord) {
	//uvec3& 分辨率 = m_Data.m_域属性.m_单元属性.m_分辨率;

	//uint32 index = (coord.z * 分辨率.x * 分辨率.y) + (coord.y * 分辨率.y) + coord.x;

	//return m_cpuIndexsNum[index];
	return false;
}

/*uint64 S_邻接单元构建::f_从坐标取索引(const vec3& coord) {
	uvec3 域坐标 = vec_转换(vec_Max((coord - m_Data.m_域属性.m_域世界偏移), { 0,0,0 }) / m_Data.m_域属性.m_单元属性.m_单元大小);

	uvec4 分辨率 = m_Data.m_域属性.m_单元属性.m_分辨率;
	uint64 id = f_坐标转线性索引(域坐标, { 分辨率.x, 分辨率.y, 分辨率.z });

	id = m_cpu索引体素[id];

	return id;
}

uint64 S_邻接单元构建::f_从坐标取索引(const uvec3& coord) {
	uvec4 分辨率 = m_Data.m_域属性.m_单元属性.m_分辨率;
	return (coord.z * 分辨率.x * 分辨率.y) + (coord.y * 分辨率.y) + coord.x;;
}*/






